package com.example.demo.config.shiro;

import com.example.demo.config.jwt.JwtProperties;
import com.example.demo.config.jwt.JwtToken;
import com.example.demo.config.jwt.JwtUtil;
import com.example.demo.entity.Person;
import com.example.demo.service.LoginService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * 自定义的 Realm 这里进行 用户认证和授权的操作
 * 我们这里假定 user_lev =1 就是用户的操作，user_lev=2 就是 管理员的操作
 */
public class ShiroRealm extends AuthorizingRealm {

    /**
     * 必须重写此方法，不然Shiro会报错
     * 不清楚是不是正确的
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Autowired
    LoginService loginService;


    /**
     * 这里进行授权，授权部分基本上 不用改,这个是token
     * @param authToken
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection authToken) {

        System.out.println("=======授权=====");
        String token=(String)authToken.getPrimaryPrincipal();

        System.out.println("这个是token 的信息 "+token);

        String name= JwtUtil.getClaim(token,JwtProperties.ACCOUNT);

        // 查询数据库，获取 角色信息
        Person person=loginService.selectPersonByName(name);
        int lev=person.getUser_lev();

        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();

        // 等级为 1 ,就是 user
        if(lev==1){
            simpleAuthorizationInfo.addRole("user");
            // 等级为 2 ,就是 admin
        }else{
            simpleAuthorizationInfo.addRole("admin");
        }
        return simpleAuthorizationInfo;
    }



    /**
     * 认证是否有这个用户
     * 认证的话需要改动
     * @param authenticationToken 身份认证的token
     * @return 身份认证的信息
     * @throws AuthenticationException 认证失败的异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        // 1. 获取传递过来的 token
        // 这个是 token 是从JwtFilter 的executeLogin 传过来的
        String token=(String) authenticationToken.getPrincipal();
        System.out.println("===shiro 认证====");
        // 这个是验证
        if(!JwtUtil.verify(token)) {
            System.out.println("校验不通过");
            throw new AuthenticationException("token校验不通过");
        }

        // 2. 根据 token 中的accout ，找出用户名
        String name= JwtUtil.getClaim(token, JwtProperties.ACCOUNT);
        Person person=loginService.selectPersonByName(name);
        System.out.println("=======认证=====");
        System.out.println(name);
        // 表示有这个用户
        if(person!=null&&person.getUser_name()!=null){

            // 这里是 和 谁验证呢？？ 这个是 和 JwtFileter 中 jwttoken 验证
            SimpleAuthenticationInfo simpleAuthorizationInfo=new SimpleAuthenticationInfo(token,token,this.getName());
            return simpleAuthorizationInfo;
        }
        return null;
    }
}
